home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / class.h < prev    next >
C/C++ Source or Header  |  1999-11-03  |  44KB  |  1,567 lines

  1. // $Id: class.h,v 1.14 1999/11/03 00:46:30 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef class_INCLUDED
  11. #define class_INCLUDED
  12.  
  13. #include "config.h"
  14. #include <stdio.h>
  15. #include "semantic.h"
  16. #include "access.h"
  17. #include "tuple.h"
  18. #include "op.h"
  19.  
  20.  
  21. class cp_info
  22. {
  23. protected:
  24.     u1 tag;
  25.  
  26.     //
  27.     //    u1 info[]
  28.     //
  29.     // cp_info can be viewed as a generic (abstract, in Java talk) class that must
  30.     // be "extended" to implement the real constant pool objects. The real objects
  31.     // contain the info...
  32.     //
  33.  
  34. public:
  35.  
  36.     cp_info(u1 _tag) : tag(_tag) {}
  37.     virtual ~cp_info() {}
  38.  
  39.     u1 Tag() { return tag; }
  40.  
  41.     virtual void Put(OutputBuffer &output_buffer)
  42.     {
  43.          assert("trying to put unsupported attribute kind" == NULL);
  44.     }
  45.  
  46. #ifdef TEST
  47.     virtual void Print(Tuple<cp_info *>& constant_pool)
  48.     {
  49.         Coutput << (int) tag;
  50.     }
  51.  
  52.     virtual void Describe(Tuple<cp_info *>& constant_pool)
  53.     {
  54.         Coutput << (int) tag;
  55.     }
  56. #endif
  57. };
  58.  
  59.  
  60. class CONSTANT_Class_info : public cp_info
  61. {
  62.     //
  63.     //    u1 tag;
  64.     //
  65.     // The tag is inherited from cp_info
  66.     //
  67.     u2 name_index;
  68.  
  69. public:
  70.  
  71.     CONSTANT_Class_info(u1 _tag, u2 _name_index) : cp_info(_tag),
  72.                                                    name_index(_name_index)
  73.     {}
  74.     virtual ~CONSTANT_Class_info() {}
  75.  
  76.     virtual void Put(OutputBuffer &output_buffer)
  77.     {
  78.         output_buffer.PutB1(tag);
  79.         output_buffer.PutB2(name_index);
  80.     }
  81.  
  82. #ifdef TEST
  83.     virtual void Print(Tuple<cp_info *>& constant_pool)
  84.     {
  85.         Coutput << "CONSTANT_Class_info: name_index " << (unsigned) name_index << "\n";
  86.     }
  87.  
  88.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  89.     {
  90.         Coutput << "Class:";  constant_pool[name_index] -> Describe(constant_pool);
  91.     }
  92. #endif
  93. };
  94.  
  95.  
  96. class CONSTANT_Double_info : public cp_info
  97. {
  98.     //
  99.     //    u1 tag;
  100.     //
  101.     // The tag is inherited from cp_info
  102.     //
  103.     u4 high_bytes;
  104.     u4 low_bytes;
  105.  
  106. public:
  107.  
  108.     CONSTANT_Double_info(u1 _tag, u4 _high_bytes, u4 _low_bytes) : cp_info(_tag),
  109.                                                                    high_bytes(_high_bytes),
  110.                                                                    low_bytes(_low_bytes)
  111.     {}
  112.     virtual ~CONSTANT_Double_info() {}
  113.  
  114.     virtual void Put(OutputBuffer &output_buffer)
  115.     {
  116.         output_buffer.PutB1(tag);
  117.         output_buffer.PutB4(high_bytes);
  118.         output_buffer.PutB4(low_bytes);
  119.     }
  120.  
  121. #ifdef TEST
  122.     virtual void Print(Tuple<cp_info *> &constant_pool)
  123.     {
  124.         Coutput << "CONSTANT_Double_info: bytes " << BaseLong(high_bytes, low_bytes).DoubleView() << "\n";
  125.     }
  126.  
  127.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  128.     {
  129.         Coutput << "D:";
  130.     }
  131. #endif
  132. };
  133.  
  134.  
  135. class CONSTANT_Fieldref_info : public cp_info
  136. {
  137.     //
  138.     //    u1 tag;
  139.     //
  140.     // The tag is inherited from cp_info
  141.     //
  142.     u2 class_index;
  143.     u2 name_and_type_index;
  144.  
  145. public:
  146.  
  147.     CONSTANT_Fieldref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  148.                                                                                 class_index(_class_index),
  149.                                                                                 name_and_type_index(_name_and_type_index)
  150.     {}
  151.     virtual ~CONSTANT_Fieldref_info() {}
  152.  
  153.     virtual void Put(OutputBuffer &output_buffer)
  154.     {
  155.          output_buffer.PutB1(tag);
  156.          output_buffer.PutB2(class_index);
  157.          output_buffer.PutB2(name_and_type_index);
  158.     }
  159.  
  160. #ifdef TEST
  161.     virtual void Print(Tuple<cp_info *> &constant_pool)
  162.     {
  163.         Coutput << "CONSTANT_Fieldref_info: class_index: "
  164.                 << (unsigned) class_index
  165.                 << ", name_and_type_index: "
  166.                 << (unsigned) name_and_type_index
  167.                 << "\n";
  168.     }
  169.  
  170.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  171.     {
  172.         constant_pool[class_index] -> Describe(constant_pool);
  173.         Coutput << ".";
  174.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  175.     }
  176. #endif
  177. };
  178.  
  179.  
  180. class CONSTANT_Float_info : public cp_info
  181. {
  182.     //
  183.     //    u1 tag;
  184.     //
  185.     // The tag is inherited from cp_info
  186.     //
  187.     u4 bytes;
  188.  
  189. public:
  190.  
  191.     CONSTANT_Float_info(u1 _tag, u4 _bytes) : cp_info(_tag),
  192.                                               bytes(_bytes)
  193.     {}
  194.     virtual ~CONSTANT_Float_info() {}
  195.  
  196.     virtual void Put(OutputBuffer &output_buffer)
  197.     {
  198.         output_buffer.PutB1(tag);
  199.         output_buffer.PutB4(bytes);
  200.     }
  201.  
  202. #ifdef TEST
  203.     virtual void Print(Tuple<cp_info *> &constant_pool)
  204.     {
  205.         Coutput << "CONSTANT_Float_info: bytes " << (float) bytes << "\n";
  206.     }
  207.  
  208.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  209.     {
  210.         Coutput << "F:";
  211.     }
  212. #endif
  213. };
  214.  
  215.  
  216. class CONSTANT_Integer_info : public cp_info
  217. {
  218.     //
  219.     //    u1 tag;
  220.     //
  221.     // The tag is inherited from cp_info
  222.     //
  223.     u4 bytes;
  224.  
  225. public:
  226.  
  227.     CONSTANT_Integer_info(u1 _tag, u4 _bytes) : cp_info(_tag),
  228.                                                 bytes(_bytes)
  229.     {}
  230.     virtual ~CONSTANT_Integer_info() {}
  231.  
  232.     virtual void Put(OutputBuffer &output_buffer)
  233.     {
  234.         output_buffer.PutB1(tag);
  235.         output_buffer.PutB4(bytes);
  236.     }
  237.  
  238. #ifdef TEST
  239.     virtual void Print(Tuple<cp_info *> &constant_pool)
  240.     {
  241.         int val = ((bytes >> 24) & 0xff) << 24 | ((bytes >> 16) & 0xff) << 16 | ((bytes >> 8) & 0xff) << 8 | (bytes & 0xff);
  242.         Coutput << "CONSTANT_Integer_info: bytes "
  243.                 << val
  244.                 << "\n";
  245.     }
  246.  
  247.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  248.     {
  249.         Coutput << "I:";
  250.     }
  251. #endif
  252. };
  253.  
  254.  
  255. class CONSTANT_InterfaceMethodref_info : public cp_info
  256. {
  257.     //
  258.     //    u1 tag;
  259.     //
  260.     // The tag is inherited from cp_info
  261.     //
  262.     u2 class_index;
  263.     u2 name_and_type_index;
  264.  
  265. public:
  266.  
  267.     CONSTANT_InterfaceMethodref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  268.                                                                                           class_index(_class_index),
  269.                                                                                           name_and_type_index(_name_and_type_index)
  270.     {}
  271.     virtual ~CONSTANT_InterfaceMethodref_info() {}
  272.  
  273.     virtual void Put(OutputBuffer &output_buffer)
  274.     {
  275.         output_buffer.PutB1(tag);
  276.         output_buffer.PutB2(class_index);
  277.         output_buffer.PutB2(name_and_type_index);
  278.     }
  279.  
  280. #ifdef TEST
  281.     virtual void Print(Tuple<cp_info *> &constant_pool)
  282.     {
  283.         Coutput << "CONSTANT_InterfaceMethodref_info: class_index: "
  284.                 << (unsigned) class_index
  285.                 << ", name_and_type_index: "
  286.                 << (unsigned) name_and_type_index
  287.                 << "\n";
  288.     }
  289.  
  290.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  291.     {
  292.         constant_pool[class_index] -> Describe(constant_pool);
  293.         Coutput << ".";
  294.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  295.     }
  296. #endif
  297. };
  298.  
  299.  
  300. class CONSTANT_Long_info : public cp_info
  301. {
  302.     //
  303.     // u1 tag;
  304.     //
  305.     // The tag is inherited from cp_info
  306.     //
  307.     u4 high_bytes;
  308.     u4 low_bytes;
  309.  
  310. public:
  311.  
  312.     CONSTANT_Long_info(u1 _tag, u4 _high_bytes, u4 _low_bytes) : cp_info(_tag),
  313.                                                                  high_bytes(_high_bytes),
  314.                                                                  low_bytes(_low_bytes)
  315.     {}
  316.     virtual ~CONSTANT_Long_info() {}
  317.  
  318.     virtual void Put(OutputBuffer &output_buffer)
  319.     {
  320.         output_buffer.PutB1(tag);
  321.         output_buffer.PutB4(high_bytes);
  322.         output_buffer.PutB4(low_bytes);
  323.     }
  324.  
  325. #ifdef TEST
  326.     virtual void Print(Tuple<cp_info *> &constant_pool)
  327.     {
  328.         Coutput << "CONSTANT_Long_info: bytes \n";
  329.     }
  330.  
  331.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  332.     {
  333.         Coutput << "L:";
  334.     }
  335. #endif
  336. };
  337.  
  338.  
  339. class CONSTANT_Methodref_info : public cp_info
  340. {
  341.     //
  342.     //    u1 tag;
  343.     //
  344.     // The tag is inherited from cp_info
  345.     //
  346.     u2 class_index;
  347.     u2 name_and_type_index;
  348.  
  349. public:
  350.  
  351.     CONSTANT_Methodref_info(u1 _tag, u2 _class_index, u2 _name_and_type_index) : cp_info(_tag),
  352.                                                                                  class_index(_class_index),
  353.                                                                                  name_and_type_index(_name_and_type_index)
  354.     {}
  355.     virtual ~CONSTANT_Methodref_info() {}
  356.  
  357.     virtual void Put(OutputBuffer &output_buffer)
  358.     {
  359.         output_buffer.PutB1(tag);
  360.         output_buffer.PutB2(class_index);
  361.         output_buffer.PutB2(name_and_type_index);
  362.     }
  363.  
  364. #ifdef TEST
  365.     virtual void Print(Tuple<cp_info *> &constant_pool)
  366.     {
  367.         Coutput << "CONSTANT_Methodref_info: class_index: "
  368.                 << (unsigned) class_index
  369.                 << ", name_and_type_index: "
  370.                 << (unsigned) name_and_type_index
  371.                 << "\n";
  372.     }
  373.  
  374.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  375.     {
  376.         constant_pool[class_index] -> Describe(constant_pool);
  377.         Coutput << ".";
  378.         constant_pool[name_and_type_index] -> Describe(constant_pool);
  379.     }
  380. #endif
  381. };
  382.  
  383.  
  384. class CONSTANT_NameAndType_info : public cp_info
  385. {
  386.     //
  387.     //    u1 tag;
  388.     //
  389.     // The tag is inherited from cp_info
  390.     //
  391.     u2 name_index;
  392.     u2 descriptor_index;
  393.  
  394. public:
  395.  
  396.     CONSTANT_NameAndType_info(u1 _tag, u2 _name_index, u2 _descriptor_index) : cp_info(_tag),
  397.                                                                                name_index(_name_index),
  398.                                                                                descriptor_index(_descriptor_index)
  399.     {}
  400.     virtual ~CONSTANT_NameAndType_info() {}
  401.  
  402.     virtual void Put(OutputBuffer &output_buffer)
  403.     {
  404.         output_buffer.PutB1(tag);
  405.         output_buffer.PutB2(name_index);
  406.         output_buffer.PutB2(descriptor_index);
  407.     }
  408.  
  409. #ifdef TEST
  410.     virtual void Print(Tuple<cp_info *> &constant_pool)
  411.     {
  412.         Coutput << "CONSTANT_NameAndType_info: name_index: "
  413.                 << (unsigned) name_index
  414.                 << ", descriptor_index: "
  415.                 << (unsigned) descriptor_index
  416.                 << "\n";
  417.     }
  418.  
  419.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  420.     {
  421.         constant_pool[name_index] -> Describe(constant_pool);
  422.         Coutput << " ";
  423.         constant_pool[descriptor_index] -> Describe(constant_pool);
  424.     }
  425. #endif
  426. };
  427.  
  428.  
  429. class CONSTANT_String_info : public cp_info
  430. {
  431.     //
  432.     //    u1 tag;
  433.     //
  434.     // The tag is inherited from cp_info
  435.     //
  436.     u2 string_index;
  437.  
  438. public:
  439.     CONSTANT_String_info(u1 _tag, u2 _string_index) : cp_info(_tag),
  440.                                                       string_index(_string_index)
  441.     {}
  442.     virtual ~CONSTANT_String_info() {}
  443.  
  444.     virtual void Put(OutputBuffer &output_buffer)
  445.     {
  446.         output_buffer.PutB1(tag);
  447.         output_buffer.PutB2(string_index);
  448.     }
  449.  
  450. #ifdef TEST
  451.     virtual void Print(Tuple<cp_info *> &constant_pool)
  452.     {
  453.         Coutput << "CONSTANT_String_info: string_index: "
  454.                 << (unsigned) string_index
  455.                 << "\n";
  456.     }
  457.  
  458.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  459.     {
  460.         constant_pool[string_index] -> Describe(constant_pool);
  461.     }
  462. #endif
  463. };
  464.  
  465.  
  466. class CONSTANT_Utf8_info : public cp_info
  467. {
  468.     //
  469.     //    u1 tag;
  470.     //
  471.     // The tag is inherited from cp_info
  472.     //
  473.     u2 length_;
  474.     char *bytes; /* bytes[length + 1] ... after input a '\0' will be added. */
  475.  
  476. public:
  477.  
  478.     CONSTANT_Utf8_info(u1 _tag, char *_bytes, int _length) : cp_info(_tag),
  479.                                                              length_(_length)
  480.     {
  481.         bytes = new char[_length];
  482.         for (int i = 0; i < _length; i++)
  483.             bytes[i] = _bytes[i];
  484.  
  485.         return;
  486.     }
  487.     virtual ~CONSTANT_Utf8_info()
  488.     {
  489.         delete [] bytes;
  490.     }
  491.  
  492.     u2 length() { return length_; }
  493.  
  494.     virtual void Put(OutputBuffer &output_buffer)
  495.     {
  496.         output_buffer.PutB1(tag);
  497.         output_buffer.PutB2(length());
  498.         for (int i = 0; i < length(); i++)
  499.             output_buffer.PutB1(bytes[i]);
  500.     }
  501.  
  502. #ifdef TEST
  503.     virtual void Print(Tuple<cp_info *> &constant_pool)
  504.     {
  505.         Coutput << "CONSTANT_Utf8_info: length: "
  506.                 << (unsigned) length_
  507.                 << " ";
  508.  
  509.         for (int i = 0; i < length_; i++)
  510.             Coutput << (char) bytes[i];
  511.         Coutput << "\n";
  512.     }
  513.  
  514.     virtual void Describe(Tuple<cp_info *> &constant_pool)
  515.     {
  516.         Coutput << "\"";
  517.         for (int i = 0; i < length_; i++)
  518.             Coutput << (char) bytes[i];
  519.         Coutput << "\"";
  520.     }
  521. #endif
  522. };
  523.  
  524.  
  525. //
  526. // field_info and method_info should be defined here, but they contain attributes, so it is necessary
  527. // to define the attributes first.
  528. //
  529.  
  530. class attribute_info
  531. {
  532. protected:
  533.     u1 tag; // this field was added in order to distinguish the attributes...
  534.  
  535.     u2 attribute_name_index;
  536.  
  537.     //
  538.     //    u2 attribute_length;
  539.     //    u1 info[attribute_length];
  540.     //
  541.     // attribute_info can be viewed as a generic (abstract, in Java talk) class that must
  542.     // be "extended" to implement the real attribute objects. The real objects
  543.     // contain the info...
  544.     //
  545.  
  546. public:
  547.     enum
  548.     {
  549.         Generic,
  550.         Code,
  551.         ConstantValue,
  552.         Deprecated,
  553.         Exceptions,
  554.         InnerClasses,
  555.         LineNumberTable,
  556.         LocalVariableTable,
  557.         SourceFile,
  558.         Synthetic
  559.     };
  560.  
  561.     attribute_info(u1 _tag, u2 _name_index) : tag(_tag),
  562.                                               attribute_name_index(_name_index)
  563.     {}
  564.     virtual ~attribute_info() {};
  565.  
  566.     u1 Tag() { return tag; }
  567.     u2 AttributeNameIndex() { return attribute_name_index; }
  568.  
  569.     virtual u4 AttributeLength() { assert(false); return 0; } // abstract method: should not be invoked.
  570.  
  571.     virtual void Put(OutputBuffer &output_buffer) { assert(false); } // abstract method: should not be invoked.
  572.  
  573. #ifdef TEST
  574.     virtual void Print(Tuple<cp_info *> &constant_pool)
  575.     {
  576.         Coutput << "print for attribute info tag "
  577.                 << (unsigned) tag
  578.                 << " not defined\n";
  579.         Coutput.flush();
  580.         assert(false); // abstract method: should not be invoked.
  581.     }
  582. #endif
  583. };
  584.  
  585.  
  586. class Code_attribute : public attribute_info
  587. {
  588.     //
  589.     //    u2 attribute_name_index;
  590.     //
  591.     // The attribut_name_index is inherited from attribute_info
  592.     //
  593.     u4 attribute_length;
  594.     u2 max_stack;
  595.     u2 max_locals;
  596.  
  597.     //
  598.     //    u4 code_length;
  599.     //
  600.     // code_length can be computed as code.Length();
  601.     //
  602.     Tuple<u1> code; /* code[code_length] */
  603.  
  604.     //
  605.     //    u2 exception_table_length;
  606.     //
  607.     // exception_table_length can be computed as exception_table.Length();
  608.     //
  609.     struct ExceptionElement
  610.     {
  611.         u2 start_pc;
  612.         u2 end_pc;
  613.         u2 handler_pc;
  614.         u2 catch_type;
  615.     };
  616.     Tuple<ExceptionElement> exception_table; /* exceptiontable[exception_table_length] */
  617.  
  618.     //
  619.     //    u2 attribute_count;
  620.     //
  621.     // attribute_count can be computed as attributes.Length();
  622.     //
  623.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  624.  
  625. public:
  626.  
  627.     Code_attribute(u2 _name_index, u2 _max_locals) : attribute_info(Code, _name_index),
  628.                                                      attribute_length(0),
  629.                                                      max_stack(0),
  630.                                                      max_locals(_max_locals),
  631.                                                      code(8, 4),
  632.                                                      exception_table(6, 16),
  633.                                                      attributes(6, 16)
  634.     {}
  635.     virtual ~Code_attribute()
  636.     {
  637.         for (int i = 0; i < attributes.Length(); i++)
  638.             delete attributes[i];
  639.     }
  640.  
  641.     virtual u4 AttributeLength()
  642.     {
  643.         if (attribute_length == 0) // if not yet computed...
  644.         {
  645.             attribute_length = + 2                            // for max_stack
  646.                                + 2                            // for max_locals
  647.                                + 4                            // for code_length
  648.                                + code.Length()                // for code
  649.                                + 2                            // for exception_table_length
  650.                                + exception_table.Length() * 8 // for exception table
  651.                                + 2;                           // for attributes_count
  652.             //
  653.             // std. fields of attribute_info
  654.             //
  655.             for (int i = 0; i < attributes.Length(); i++)
  656.             {
  657.                 if (attributes[i] -> AttributeLength() > 0)
  658.                     attribute_length += (attributes[i] -> AttributeLength() + 6);
  659.             }
  660.         }
  661.  
  662.         return attribute_length;
  663.     }
  664.  
  665.     u2 MaxStack() { return max_stack; }
  666.     void SetMaxStack(u2 val) { max_stack = val; }
  667.  
  668.     u2 MaxLocals() { return max_locals; }
  669.     void ResetMaxLocals(u2 val) { max_locals = val; }
  670.  
  671.     u2 CodeLength() { return code.Length(); }
  672.  
  673.     void ResetCode(int i, u1 byte)
  674.     {
  675.         code[i] = byte;
  676.     }
  677.  
  678.     void AddCode(u1 byte)
  679.     {
  680.         code.Next() = byte;
  681.     }
  682.  
  683.     u2 ExceptionTableLength() { return exception_table.Length(); }
  684.  
  685.     void AddException(u2 start_pc, u2 end_pc, u2 handler_pc, u2 catch_type)
  686.     {
  687.         int exception_index = exception_table.NextIndex();
  688.  
  689.         exception_table[exception_index].start_pc = start_pc;
  690.         exception_table[exception_index].end_pc = end_pc;
  691.         exception_table[exception_index].handler_pc = handler_pc;
  692.         exception_table[exception_index].catch_type = catch_type;
  693.     }
  694.  
  695.     u2 AttributesCount() { return attributes.Length(); }
  696.  
  697.     void AddAttribute(attribute_info *attribute)
  698.     {
  699.         attributes.Next() = attribute;
  700.     }
  701.  
  702.     virtual void Put(OutputBuffer &output_buffer)
  703.     {
  704.         assert(attribute_name_index != 0);
  705.  
  706.         output_buffer.PutB2(attribute_name_index);
  707.         output_buffer.PutB4(AttributeLength());
  708.         output_buffer.PutB2(max_stack);
  709.         output_buffer.PutB2(max_locals);
  710.         output_buffer.PutB4(code.Length());
  711.  
  712.         for (int i = 0; i < code.Length(); i++)
  713.             output_buffer.PutB1(code[i]);
  714.         output_buffer.PutB2(exception_table.Length());
  715.  
  716.         for (int j = 0; j < exception_table.Length(); j++)
  717.         {
  718.             output_buffer.PutB2(exception_table[j].start_pc);
  719.             output_buffer.PutB2(exception_table[j].end_pc);
  720.             output_buffer.PutB2(exception_table[j].handler_pc);
  721.             output_buffer.PutB2(exception_table[j].catch_type);
  722.         }
  723.  
  724.         output_buffer.PutB2(attributes.Length());
  725.         for (int k = 0; k < attributes.Length(); k++)
  726.             attributes[k] -> Put(output_buffer);
  727.  
  728.         return;
  729.     }
  730.  
  731. #ifdef TEST
  732.     virtual void  Print(Tuple<cp_info *> &constant_pool)
  733.     {
  734.         Coutput << "Code_attribute attribute_name_index "
  735.                 << (unsigned) attribute_name_index
  736.                 << " attribute_length "
  737.                 << (unsigned) attribute_length
  738.                 << "\n"
  739.                 << " max_stack "
  740.                 << (unsigned) max_stack
  741.                 << " max_locals "
  742.                 << (unsigned) max_locals
  743.                 << " code_length "
  744.                 << code.Length()
  745.                 << "\n";
  746.  
  747.         if (exception_table.Length())
  748.         {
  749.             Coutput << " exception_table: " << exception_table.Length() << " entries\n";
  750.             for (int i  = 0; i < exception_table.Length(); i++)
  751.             {
  752.                 Coutput << "  start_pc "
  753.                         << (unsigned) exception_table[i].start_pc
  754.                         << "  end_pc "
  755.                         << (unsigned) exception_table[i].end_pc
  756.                         << "  handler_pc "
  757.                         << (unsigned) exception_table[i].handler_pc
  758.                         << "  catch_type "
  759.                         << (unsigned) exception_table[i].catch_type
  760.                         << "\n";
  761.             }
  762.         }
  763.  
  764.         Operators::opdmp(constant_pool, code);
  765.  
  766.         Coutput << "  \n";
  767.  
  768.         for (int i = 0; i < attributes.Length(); i++)
  769.             attributes[i] -> Print(constant_pool);
  770.     }
  771. #endif
  772. };
  773.  
  774.  
  775. class ConstantValue_attribute : public attribute_info
  776. {
  777.     //
  778.     //    u2 attribute_name_index;
  779.     //
  780.     // The field attribute_name_index is inherited from attribute_info
  781.     //
  782.     //    u4 attribute_length;
  783.     //
  784.     // The value of attribute_length is always 2
  785.     //
  786.     u2 constantvalue_index;
  787.  
  788. public:
  789.  
  790.     ConstantValue_attribute(u2 _name_index, u2 _constantvalue_index) : attribute_info(ConstantValue, _name_index),
  791.                                                                        constantvalue_index(_constantvalue_index)
  792.     {}
  793.     virtual ~ConstantValue_attribute() {}
  794.  
  795.     virtual u4 AttributeLength() { return 2; }
  796.  
  797.     virtual void Put(OutputBuffer &output_buffer)
  798.     {
  799.         assert(attribute_name_index != 0);
  800.  
  801.         output_buffer.PutB2(attribute_name_index);
  802.         output_buffer.PutB4(AttributeLength());
  803.         output_buffer.PutB2(constantvalue_index);
  804.     }
  805.  
  806. #ifdef TEST
  807.     virtual void Print(Tuple<cp_info *> &constant_pool)
  808.     {
  809.         Coutput << "ConstantValue_attribute attribute_name_index "
  810.                 << (unsigned) attribute_name_index
  811.                 << " attribute_length "
  812.                 << AttributeLength()
  813.                 << " constantvalue_index "
  814.                 << (unsigned) constantvalue_index
  815.                 << "\n";
  816.     }
  817. #endif
  818. };
  819.  
  820.  
  821. class Exceptions_attribute : public attribute_info
  822. {
  823.     //
  824.     //    u2 attribute_name_index;
  825.     //
  826.     // The fields attribute_name_index is inherited from attribute_info
  827.     //
  828.     //    u4 attribute_length;
  829.     //
  830.     // The value of attribute_length is derived from the exception_index_table. See below
  831.     //
  832.     //    u2 number_of_exceptions;
  833.     //
  834.     // The value of number_of_exceptions is derived from the exception_index_table. See below
  835.     //
  836.  
  837.     Tuple<u2> exception_index_table; /* exception_index_table[number_of_exceptions] */
  838.  
  839. public:
  840.  
  841.     Exceptions_attribute(u2 _name_index) : attribute_info(Exceptions, _name_index)
  842.     {}
  843.     virtual ~Exceptions_attribute() {}
  844.  
  845.     virtual u4 AttributeLength()
  846.     {
  847.         return exception_index_table.Length() * 2 + 2;
  848.     }
  849.  
  850.     u2 NumberOfExceptions() { return exception_index_table.Length(); }
  851.  
  852.     void AddExceptionIndex(u2 index)
  853.     {
  854.         exception_index_table.Next() = index;
  855.     }
  856.  
  857.     virtual void Put(OutputBuffer &output_buffer)
  858.     {
  859.         assert(attribute_name_index != 0);
  860.  
  861.         output_buffer.PutB2(attribute_name_index);
  862.         output_buffer.PutB4(AttributeLength());
  863.         output_buffer.PutB2(exception_index_table.Length());
  864.         for (int i = 0; i < exception_index_table.Length(); i++)
  865.             output_buffer.PutB2(exception_index_table[i]);
  866.     }
  867.  
  868. #ifdef TEST
  869.     virtual void Print(Tuple<cp_info *> &constant_pool)
  870.     {
  871.         Coutput << "Exceptions_attribute attribute_name_index "
  872.                 << (unsigned) attribute_name_index
  873.                 << " attribute_length "
  874.                 << AttributeLength()
  875.                 << "\n";
  876.  
  877.         for (int i = 0; i < exception_index_table.Length(); i++)
  878.             Coutput << "    "
  879.                     << (unsigned) exception_index_table[i];
  880.         Coutput << "\n";
  881.     }
  882. #endif
  883. };
  884.  
  885.  
  886. class InnerClasses_attribute : public attribute_info
  887. {
  888.     //
  889.     //    u2 attribute_name_index;
  890.     //
  891.     // The fields attribute_name_index is inherited from attribute_info
  892.     //
  893.     //    u4 attribute_length;
  894.     //
  895.     // The value of attribute_length is derived from inner_classes. See below
  896.     //
  897.     //    u2 number_of_classes;
  898.     //
  899.     // The value of number_of_classes is derived from inner_classes. See below
  900.     //
  901.  
  902.     struct inner_classes_element
  903.     {
  904.         u2 inner_class_info_index;
  905.         u2 outer_class_info_index;
  906.         u2 inner_name_index;
  907.         u2 inner_class_access_flags;
  908.     };
  909.     Tuple<inner_classes_element> inner_classes; /* inner_classes_table[inner_classes_table_length] */
  910.  
  911. public:
  912.  
  913.     InnerClasses_attribute(u2 _name_index) : attribute_info(InnerClasses, _name_index),
  914.                                              inner_classes(6, 16)
  915.     {}
  916.     virtual ~InnerClasses_attribute() {}
  917.  
  918.     virtual u4 AttributeLength()
  919.     {
  920.         return inner_classes.Length() * 8 + 2;
  921.     }
  922.  
  923.     u2 InnerClassesLength() { return inner_classes.Length();}
  924.  
  925.     void AddInnerClass(u2 inner_class_info_index, u2 outer_class_info_index, u2 inner_name_index, u2 inner_class_access_flags)
  926.     {
  927.         int index = inner_classes.NextIndex();
  928.  
  929.         inner_classes[index].inner_class_info_index = inner_class_info_index;
  930.         inner_classes[index].outer_class_info_index = outer_class_info_index;
  931.         inner_classes[index].inner_name_index = inner_name_index;
  932.         inner_classes[index].inner_class_access_flags = inner_class_access_flags;
  933.     }
  934.  
  935.     virtual void Put(OutputBuffer &output_buffer)
  936.     {
  937.         assert(attribute_name_index != 0);
  938.  
  939.         output_buffer.PutB2(attribute_name_index);
  940.         output_buffer.PutB4(AttributeLength());
  941.         output_buffer.PutB2(inner_classes.Length());
  942.         for (int i = 0; i < inner_classes.Length(); i++)
  943.         {
  944.             output_buffer.PutB2(inner_classes[i].inner_class_info_index);
  945.             output_buffer.PutB2(inner_classes[i].outer_class_info_index);
  946.             output_buffer.PutB2(inner_classes[i].inner_name_index);
  947.             output_buffer.PutB2(inner_classes[i].inner_class_access_flags);
  948.         }
  949.     }
  950.  
  951. #ifdef TEST
  952.     virtual void Print(Tuple<cp_info *> &constant_pool)
  953.     {
  954.         Coutput << "InnerClasses_attribute attribute_name_index "
  955.                 << (unsigned) attribute_name_index
  956.                 << " attribute_length "
  957.                 << AttributeLength()
  958.                 << "\n"
  959.                 << " inner_classes_length "
  960.                 << inner_classes.Length()
  961.                 << "\n";
  962.  
  963.         for (int i = 0; i < inner_classes.Length(); i++)
  964.         {
  965.             Coutput << "     "
  966.                     << i
  967.                     << "  inner_class_info_index "
  968.                     << (unsigned) inner_classes[i].inner_class_info_index
  969.                     << "  outer_class_info_index "
  970.                     << (unsigned) inner_classes[i].outer_class_info_index
  971.                     << "  inner_name_index "
  972.                     << (unsigned) inner_classes[i].inner_name_index
  973.                     << "  inner_class_access_flags "
  974.                     << (unsigned) inner_classes[i].inner_class_access_flags
  975.                     << "\n";
  976.         }
  977.     }
  978. #endif
  979. };
  980.  
  981.  
  982. class LineNumberTable_attribute : public attribute_info
  983. {
  984.     //
  985.     //    u2 attribute_name_index;
  986.     //
  987.     // The fields attribute_name_index is inherited from attribute_info
  988.     //
  989.     //    u4 attribute_length;
  990.     //
  991.     // The value of attribute_length is derived from line_number_table. See below
  992.     //
  993.     //    u2 line_number_table_length;
  994.     //
  995.     // The value of line_number_table_length is derived from line_number_table. See below
  996.     //
  997.  
  998.     struct line_number_element
  999.     {
  1000.         u2 start_pc;
  1001.         u2 line_number;
  1002.     };
  1003.     Tuple<line_number_element> line_number_table; /* line_number_table[line_number_table_length] */
  1004.  
  1005. public:
  1006.  
  1007.     LineNumberTable_attribute(u2 _name_index) : attribute_info(LineNumberTable, _name_index),
  1008.                                                 line_number_table(6, 16)
  1009.     {}
  1010.     virtual ~LineNumberTable_attribute() {}
  1011.  
  1012.     virtual u4 AttributeLength()
  1013.     {
  1014.         return line_number_table.Length() * 4 + 2;
  1015.     }
  1016.  
  1017.     u2 LineNumberTableLength()
  1018.     {
  1019.         return line_number_table.Length();
  1020.     }
  1021.  
  1022.     void AddLineNumber(u2 start_pc, u2 line_number)
  1023.     {
  1024.         int line_number_index = line_number_table.NextIndex();
  1025.  
  1026.         line_number_table[line_number_index].start_pc = start_pc;
  1027.         line_number_table[line_number_index].line_number = line_number;
  1028.     }
  1029.  
  1030.     virtual void Put(OutputBuffer &output_buffer)
  1031.     {
  1032.         assert(attribute_name_index != 0);
  1033.  
  1034.         output_buffer.PutB2(attribute_name_index);
  1035.         output_buffer.PutB4(AttributeLength());
  1036.         output_buffer.PutB2(line_number_table.Length());
  1037.         for (int i = 0; i < line_number_table.Length(); i++)
  1038.         {
  1039.             output_buffer.PutB2(line_number_table[i].start_pc);
  1040.             output_buffer.PutB2(line_number_table[i].line_number);
  1041.         }
  1042.     }
  1043.  
  1044. #ifdef TEST
  1045.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1046.      {
  1047.         Coutput << "LineNumberTable_attribute attribute_name_index "
  1048.                 << (unsigned) attribute_name_index
  1049.                 << " attribute_length "
  1050.                 << AttributeLength()
  1051.                 << "\n"
  1052.                 << " line_number_table_length "
  1053.                 << line_number_table.Length()
  1054.                 << "\n";
  1055.  
  1056.         for (int i = 0; i < line_number_table.Length(); i++)
  1057.         {
  1058.             Coutput << "     "
  1059.                     << i
  1060.                     << "  start_pc "
  1061.                     << (unsigned) line_number_table[i].start_pc
  1062.                     << "  line_number "
  1063.                     << (unsigned) line_number_table[i].line_number
  1064.                     << "\n";
  1065.         }
  1066.     }
  1067. #endif
  1068. };
  1069.  
  1070.  
  1071. class LocalVariableTable_attribute : public attribute_info
  1072. {
  1073.     //
  1074.     //    u2 attribute_name_index;
  1075.     //
  1076.     // The fields attribute_name_index is inherited from attribute_info
  1077.     //
  1078.     //    u4 attribute_length;
  1079.     //
  1080.     // The value of attribute_length is derived from local_variable_table. See below
  1081.     //
  1082.     //    u2 local_variable_length;
  1083.     //
  1084.     // The value of local_variable_length is derived from local_variable_length. See below
  1085.     //
  1086.  
  1087.     struct local_variable_element
  1088.     {
  1089.         u2 start_pc;
  1090.         u2 length;
  1091.         u2 name_index;
  1092.         u2 descriptor_index;
  1093.         u2 index;
  1094.     };
  1095.     Tuple<local_variable_element> local_variable_table; /* local_variable_table[local_variable_table_length] */
  1096.  
  1097. public:
  1098.  
  1099.     LocalVariableTable_attribute(u2 _name_index) : attribute_info(LocalVariableTable, _name_index)
  1100.     {}
  1101.     virtual ~LocalVariableTable_attribute() {}
  1102.  
  1103.     virtual u4 AttributeLength()
  1104.     {
  1105.         return local_variable_table.Length() * 10 + 2;
  1106.     }
  1107.  
  1108.     u2 LocalVariableTableLength() { return local_variable_table.Length(); }
  1109.  
  1110.     //
  1111.     // make entry in local variable table
  1112.     //
  1113.     void AddLocalVariable(u2 start, u2 end, u2 name, u2 descriptor, u2 index)
  1114.     {
  1115.         assert(end >= start);
  1116.  
  1117.         if (end > start)
  1118.         {
  1119.             int local_index = local_variable_table.NextIndex();
  1120.  
  1121.             local_variable_table[local_index].start_pc = start;
  1122.             local_variable_table[local_index].length = end - start;
  1123.             local_variable_table[local_index].name_index = name;
  1124.             local_variable_table[local_index].descriptor_index = descriptor;
  1125.             local_variable_table[local_index].index = index;
  1126.         }
  1127. else 
  1128. end = end;
  1129.  
  1130.         return;
  1131.     }
  1132.  
  1133.     virtual void Put(OutputBuffer &output_buffer)
  1134.     {
  1135.         assert(attribute_name_index != 0);
  1136.  
  1137.         output_buffer.PutB2(attribute_name_index);
  1138.         output_buffer.PutB4(AttributeLength());
  1139.         output_buffer.PutB2(local_variable_table.Length());
  1140.         for (int i = 0; i < local_variable_table.Length(); i++)
  1141.         {
  1142.             output_buffer.PutB2(local_variable_table[i].start_pc);
  1143.             output_buffer.PutB2(local_variable_table[i].length);
  1144.             output_buffer.PutB2(local_variable_table[i].name_index);
  1145.             output_buffer.PutB2(local_variable_table[i].descriptor_index);
  1146.             output_buffer.PutB2(local_variable_table[i].index);
  1147.         }
  1148.     }
  1149.  
  1150. #ifdef TEST
  1151.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1152.     {
  1153.         Coutput << "LocalVariableTable_attribute attribute_name_index "
  1154.                 << (unsigned) attribute_name_index
  1155.                 << " attribute_length "
  1156.                 << AttributeLength()
  1157.                 << "\n"
  1158.                 << " local_variable_table_length "
  1159.                 << local_variable_table.Length()
  1160.                 << "\n";
  1161.  
  1162.         for (int i = 0; i < local_variable_table.Length(); i++)
  1163.         {
  1164.             Coutput << "     "
  1165.                     << i
  1166.                     << "  start_pc "
  1167.                     << (unsigned) local_variable_table[i].start_pc
  1168.                     << "  length "
  1169.                     << (unsigned) local_variable_table[i].length
  1170.                     << "  name_index "
  1171.                     << (unsigned) local_variable_table[i].name_index
  1172.                     << "  descriptor_index "
  1173.                     << (unsigned) local_variable_table[i].descriptor_index
  1174.                     << "  index "
  1175.                     << (unsigned) local_variable_table[i].index
  1176.                     << "\n";
  1177.         }
  1178.     }
  1179. #endif
  1180. };
  1181.  
  1182.  
  1183. class SourceFile_attribute : public attribute_info
  1184. {
  1185.     //
  1186.     //    u2 attribute_name_index;
  1187.     //
  1188.     // The fields attribute_name_index is inherited from attribute_info
  1189.     //
  1190.     // The attribute_length is always 2.
  1191.     //
  1192.     u2 sourcefile_index;
  1193.  
  1194. public:
  1195.  
  1196.     SourceFile_attribute(u2 _name_index, u2 _sourcefile_index) : attribute_info(SourceFile, _name_index),
  1197.                                                                  sourcefile_index(_sourcefile_index)
  1198.     {}
  1199.     virtual ~SourceFile_attribute() {}
  1200.  
  1201.     virtual u4 AttributeLength() { return 2; }
  1202.  
  1203.     virtual void Put(OutputBuffer &output_buffer)
  1204.     {
  1205.         assert(attribute_name_index != 0);
  1206.  
  1207.         output_buffer.PutB2(attribute_name_index);
  1208.         output_buffer.PutB4(AttributeLength());
  1209.         output_buffer.PutB2(sourcefile_index);
  1210.     }
  1211.  
  1212. #ifdef TEST
  1213.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1214.     {
  1215.         Coutput << "SourceFile_attribute attribute_name_index "
  1216.                 << (unsigned) attribute_name_index
  1217.                 << " length "
  1218.                 << AttributeLength()
  1219.                 << " sourcefile_index "
  1220.                 << (unsigned) sourcefile_index
  1221.                 << "\n";
  1222.     }
  1223. #endif
  1224. };
  1225.  
  1226.  
  1227. class Synthetic_attribute : public attribute_info
  1228. {
  1229.     //
  1230.     //    u2 attribute_name_index;
  1231.     //
  1232.     // The fields attribute_name_index and attribute_length are inherited from attribute_info
  1233.     //
  1234.     // The attribute_length is always 0.
  1235.     //
  1236.  
  1237. public:
  1238.  
  1239.     Synthetic_attribute(u2 _name_index) : attribute_info(Synthetic, _name_index)
  1240.     {}
  1241.     virtual ~Synthetic_attribute() {}
  1242.  
  1243.     virtual u4 AttributeLength() { return 0; }
  1244.  
  1245.     virtual void Put(OutputBuffer &output_buffer)
  1246.     {
  1247.         assert(attribute_name_index != 0);
  1248.  
  1249.         output_buffer.PutB2(attribute_name_index);
  1250.         output_buffer.PutB4(AttributeLength());
  1251.     }
  1252.  
  1253. #ifdef TEST
  1254.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1255.     {
  1256.         Coutput << "Synthetic_attribute attribute_name_index "
  1257.                 << (unsigned) attribute_name_index
  1258.                 << " length "
  1259.                 << AttributeLength()
  1260.                 << "\n";
  1261.     }
  1262. #endif
  1263. };
  1264.  
  1265.  
  1266. class Deprecated_attribute : public attribute_info
  1267. {
  1268.     //
  1269.     //    u2 attribute_name_index;
  1270.     //
  1271.     // The fields attribute_name_index and attribute_length are inherited from attribute_info
  1272.     //
  1273.     // The attribute_length is always 0.
  1274.     //
  1275.  
  1276. public:
  1277.  
  1278.     Deprecated_attribute(u2 _name_index) : attribute_info(Deprecated, _name_index)
  1279.     {}
  1280.     virtual ~Deprecated_attribute() {}
  1281.  
  1282.     virtual u4 AttributeLength() { return 0; }
  1283.  
  1284.     virtual void Put(OutputBuffer &output_buffer)
  1285.     {
  1286.         assert(attribute_name_index != 0);
  1287.  
  1288.         output_buffer.PutB2(attribute_name_index);
  1289.         output_buffer.PutB4(AttributeLength());
  1290.     }
  1291.  
  1292. #ifdef TEST
  1293.     virtual void Print(Tuple<cp_info *> &constant_pool)
  1294.     {
  1295.         Coutput << "Deprecated_attribute attribute_name_index "
  1296.                 << (unsigned) attribute_name_index
  1297.                 << " length "
  1298.                 << AttributeLength()
  1299.                 << "\n";
  1300.     }
  1301. #endif
  1302. };
  1303.  
  1304.  
  1305. class field_info : public AccessFlags
  1306. {
  1307.     //
  1308.     // u2 access_flags;
  1309.     //
  1310.     // The access_flags is inherited from AccessFlags
  1311.     //
  1312.     u2 name_index;
  1313.     u2 descriptor_index;
  1314.  
  1315.     //
  1316.     // attributes_count can be computed as attributes.Length();
  1317.     //
  1318.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1319.  
  1320. public:
  1321.  
  1322.      ~field_info()
  1323.      {
  1324.          for (int i = 0; i < attributes.Length(); i++)
  1325.              delete attributes[i];
  1326.      }
  1327.  
  1328.     inline void SetNameIndex(u2 _name_index) { name_index = _name_index; }
  1329.     inline void SetDescriptorIndex(u2 _descriptor_index) { descriptor_index = _descriptor_index; }
  1330.  
  1331.     inline u2 AttributesCount() { return attributes.Length(); }
  1332.     inline void AddAttribute(attribute_info *attribute) { attributes.Next() = attribute; }
  1333.  
  1334.     inline void Put(OutputBuffer &output_buffer)
  1335.     {
  1336.         output_buffer.PutB2(access_flags);
  1337.         output_buffer.PutB2(name_index);
  1338.         output_buffer.PutB2(descriptor_index);
  1339.         output_buffer.PutB2(attributes.Length());
  1340.  
  1341.         for (int ai = 0; ai < attributes.Length(); ai++)
  1342.             attributes[ai] -> Put(output_buffer);
  1343.     }
  1344.  
  1345. #ifdef TEST
  1346.     void Print(Tuple<cp_info *> &constant_pool)
  1347.     {
  1348.         Coutput << "field_info  name_index "
  1349.                 << (unsigned) name_index
  1350.                 << "  descriptor_index "
  1351.                 << (unsigned) descriptor_index
  1352.                 << "\n";
  1353.  
  1354.         AccessFlags::Print();
  1355.  
  1356.         for (int i = 0; i < attributes.Length(); i++)
  1357.             attributes[i] -> Print(constant_pool);
  1358.         Coutput << "\n";
  1359.     }
  1360. #endif
  1361. };
  1362.  
  1363.  
  1364. class method_info : public AccessFlags
  1365. {
  1366.     //
  1367.     // u2 access_flags;
  1368.     //
  1369.     // The access_flags is inherited from AccessFlags
  1370.     //
  1371.     u2 name_index;
  1372.     u2 descriptor_index;
  1373.  
  1374.     //
  1375.     // attributes_count can be computed as attributes.Length();
  1376.     //
  1377.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1378.  
  1379. public:
  1380.  
  1381.     ~method_info()
  1382.     {
  1383.         for (int i = 0; i < attributes.Length(); i++)
  1384.             delete attributes[i];
  1385.     }
  1386.  
  1387.     inline void SetNameIndex(u2 _name_index) { name_index = _name_index; }
  1388.     inline void SetDescriptorIndex(u2 _descriptor_index) { descriptor_index = _descriptor_index; }
  1389.  
  1390.     inline u2 AttributesCount() { return attributes.Length(); }
  1391.     inline void AddAttribute(attribute_info *attribute) { attributes.Next() = attribute; }
  1392.  
  1393.     inline void Put(OutputBuffer &output_buffer)
  1394.     {
  1395.         output_buffer.PutB2(access_flags);
  1396.         output_buffer.PutB2(name_index);
  1397.         output_buffer.PutB2(descriptor_index);
  1398.         output_buffer.PutB2(attributes.Length());
  1399.  
  1400.         for (int i = 0; i < attributes.Length(); i++)
  1401.             attributes[i] -> Put(output_buffer);
  1402.     }
  1403.  
  1404. #ifdef TEST
  1405.      void Print(Tuple<cp_info *> &constant_pool)
  1406.      {
  1407.         Coutput << "method_info  name_index "
  1408.                 << (unsigned) name_index
  1409.                 << "  descriptor_index "
  1410.                 << (unsigned) descriptor_index
  1411.                 << "\n";
  1412.  
  1413.         AccessFlags::Print();
  1414.  
  1415.         for (int i = 0; i < attributes.Length(); i++)
  1416.             attributes[i] -> Print(constant_pool);
  1417.         Coutput << "\n";
  1418.     }
  1419. #endif
  1420. };
  1421.  
  1422.  
  1423. class ClassFile : public AccessFlags
  1424. {
  1425. public:
  1426.     enum ConstantKind
  1427.     {
  1428.         CONSTANT_Class              = 7,
  1429.         CONSTANT_Fieldref           = 9,
  1430.         CONSTANT_Methodref          = 10,
  1431.         CONSTANT_InterfaceMethodref = 11,
  1432.         CONSTANT_String             = 8,
  1433.         CONSTANT_Integer            = 3,
  1434.         CONSTANT_Float              = 4,
  1435.         CONSTANT_Long               = 5,
  1436.         CONSTANT_Double             = 6,
  1437.         CONSTANT_NameAndType        = 12,
  1438.         CONSTANT_Utf8               = 1
  1439.     };
  1440.  
  1441.     u4 magic;
  1442.     u2 minor_version;
  1443.     u2 major_version;
  1444.     u2 ConstantPoolCount() { return constant_pool.Length(); }
  1445.     Tuple<cp_info *> constant_pool; /* cp_info[constant_pool_count] */
  1446.     //
  1447.     // u2 access_flags;
  1448.     //
  1449.     // The access_flags is inherited from AccessFlags
  1450.     //
  1451.     u2 this_class;
  1452.     u2 super_class;
  1453.     u2 InterfacesCount() { return interfaces.Length(); }
  1454.     Tuple<u2> interfaces; /* interfaces[interfaces_count] */
  1455.     u2 FieldsCount() { return fields.Length(); }
  1456.     Tuple<field_info> fields; /* fields[fields_count] */
  1457.     u2 MethodsCount() { return methods.Length();}
  1458.     Tuple<method_info> methods; /* methods[methods_count] */
  1459.     u2 AttributesCount() { return attributes.Length(); }
  1460.     Tuple<attribute_info *> attributes; /* attributes[attributes_count] */
  1461.  
  1462.     ClassFile(TypeSymbol *unit_type_) : constant_pool(8, 4),
  1463.                                         fields(6, 16),
  1464.                                         methods(6, 16),
  1465.                                         unit_type(unit_type_)
  1466.     {}
  1467.  
  1468.     ~ClassFile()
  1469.     {
  1470.         for (int i = 1; i < constant_pool.Length(); i++)
  1471.             delete constant_pool[i];
  1472.  
  1473.         for (int j = 0; j < attributes.Length(); j++)
  1474.             delete attributes[j];
  1475.  
  1476.         return;
  1477.     }
  1478.  
  1479.     void Write()
  1480.     {
  1481.         Semantic *sem = unit_type -> semantic_environment -> sem;
  1482.         Control &control = sem -> control;
  1483.  
  1484.         if (! control.option.nowrite)
  1485.         {
  1486.             output_buffer.PutB4(magic);
  1487.             output_buffer.PutB2(minor_version);
  1488.             output_buffer.PutB2(major_version);
  1489.  
  1490.             //
  1491.             // write constant pool
  1492.             //
  1493.             output_buffer.PutB2(constant_pool.Length());
  1494.             for (int i = 1; i < constant_pool.Length(); i++)
  1495.             {
  1496.                 assert(constant_pool[i]);
  1497.  
  1498.                 constant_pool[i] -> Put(output_buffer);
  1499.                 if (constant_pool[i] -> Tag()  ==  CONSTANT_Long || constant_pool[i] -> Tag()  ==  CONSTANT_Double)
  1500.                     i++;; // skip the next entry for eight-byte constants
  1501.             }
  1502.  
  1503.             output_buffer.PutB2(access_flags);
  1504.             output_buffer.PutB2(this_class);
  1505.             output_buffer.PutB2(super_class);
  1506.  
  1507.             //
  1508.             // write interfaces
  1509.             //
  1510.             output_buffer.PutB2(interfaces.Length());
  1511.             for (int j = 0; j < interfaces.Length(); j++)
  1512.                 output_buffer.PutB2(interfaces[j]);
  1513.  
  1514.             //
  1515.             // write field members
  1516.             //
  1517.             output_buffer.PutB2(fields.Length());
  1518.             for (int k = 0; k < fields.Length(); k++)
  1519.                 fields[k].Put(output_buffer);
  1520.  
  1521.             //
  1522.             // write method members
  1523.             //
  1524.             output_buffer.PutB2(methods.Length());
  1525.             for (int l = 0; l < methods.Length(); l++)
  1526.                 methods[l].Put(output_buffer);
  1527.  
  1528.             //
  1529.             // write attributes
  1530.             //
  1531.             output_buffer.PutB2(attributes.Length());
  1532.             for (int m = 0; m < attributes.Length(); m++)
  1533.                 attributes[m] -> Put(output_buffer);
  1534.  
  1535.             char *class_file_name = unit_type -> ClassName();
  1536.             if (control.option.verbose)
  1537.             {
  1538.                 Coutput << "[write "
  1539.                         << class_file_name
  1540.                         << "]\n";
  1541.             }
  1542.  
  1543.             if (! output_buffer.WriteToFile(class_file_name))
  1544.             {
  1545.                 int length = strlen(class_file_name);
  1546.                 wchar_t *name = new wchar_t[length + 1];
  1547.                 for (int i = 0; i < length; i++)
  1548.                     name[i] = class_file_name[i];
  1549.                 name[length] = U_NULL;
  1550.  
  1551.                 sem -> ReportSemError(SemanticError::CANNOT_WRITE_FILE,
  1552.                                      unit_type -> declaration -> LeftToken(),
  1553.                                      unit_type -> declaration -> RightToken(),
  1554.                                      name);
  1555.                 delete [] name;
  1556.             }
  1557.         }
  1558.  
  1559.         return;
  1560.     }
  1561.  
  1562. protected:
  1563.     TypeSymbol *unit_type;
  1564.     OutputBuffer output_buffer;
  1565. };
  1566. #endif
  1567.